﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using Android;
using Android.App;
using Android.Content;
using Android.Database;
using Android.OS;
using Android.Provider;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V4.App;
using Android.Support.V4.Content;
using Android.Support.V4.View;
using Android.Support.V4.Widget;
using Android.Support.V7.App;
using Android.Views;
using Java.Net;
using Medicine.Activities;
using Medicine.Helpers;
using Org.Apache.Http.Impl.Client;
using Uri = Android.Net.Uri;

namespace Medicine
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
    public class MainActivity : AppCompatActivity, NavigationView.IOnNavigationItemSelectedListener
    {
        private Models.AppSet _appSet=new Models.AppSet();

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.activity_main);
            //注入Toolbar
            Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);

            FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
            fab.Click += FabOnClick;

            //将主页面绑定Toolbar
            DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
            Android.Support.V7.App.ActionBarDrawerToggle toggle = new Android.Support.V7.App.ActionBarDrawerToggle(this, drawer, toolbar, Resource.String.navigation_drawer_open, Resource.String.navigation_drawer_close);
            drawer.AddDrawerListener(toggle);
            toggle.SyncState();

            NavigationView navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
            //设置菜单显示彩色图片，而不是灰色。
            navigationView.ItemIconTintList = null;
            navigationView.SetNavigationItemSelectedListener(this);

            SetDb();
            InitData();

        }

        /// <summary>
        /// 进入时更新APP设置，并在返回时重新读取设置
        /// </summary>
        private void InitData()
        {
            var appSet = DbContext.DbC.FirstQuery<Models.AppSet>(f => f.Id != null && f.Id != "");
            if (appSet == null)
            {
                this._appSet.InitDefaultData();
            }
            else
            {
                this._appSet = appSet;
            }
            InitControlEvents();
            SearchOverDateMedicine();
            UpdateEvents();
        }

        protected override void OnStart()
        {
            InitData();
            base.OnStart();
        }

        #region 更新相关
        private void UpdateEvents()
        {
            try
            {
                var url = $"{this._appSet.ServerIp}:{this._appSet.ServerPort}{(this._appSet.ServerUpdateFilePath.IndexOf("/") < 0 ? "/" : "")}{this._appSet.ServerUpdateFilePath}";

                var webVersionStr = HttpHelper.HttpGet(url);
                var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(webVersionStr);
                if (data.ContainsKey("version"))
                {
                    var version = data["version"].ToString();
                    var pm = Application.PackageManager;
                    var pInfo = pm.GetPackageInfo(Application.PackageName, 0);
                    var loacalVersion = Convert.ToDouble(pInfo.VersionName);
                    var webVersion = Convert.ToDouble(version);
                    if (webVersion > loacalVersion)
                    {
                        var updateEventHandler = new EventHandler<DialogClickEventArgs>(UpdateApp);
                        MessageShow.ShowQuestionNoticeMsg(this,
                            "新版本提示",
                            "有新版本数据！是否更新？",
                            updateEventHandler,
                            null);
                    }
                }
            }
            catch (Exception)
            {
                MessageShow.ShowNoticeMsg(this, "提示", "暂时无法访问更新服务器");
            }
        }

        /// <summary>
        /// 采用后台线程下载新版本，防止界面卡顿
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arg"></param>
        public async void UpdateApp(object sender, DialogClickEventArgs arg)
        {
            CheckPermission();
            var result = Android.OS.Environment.ExternalStorageState.Equals(Android.OS.Environment.MediaMounted);

            if (result)
            {
                bool downloadIsSuccess = false;
                var url = $"{this._appSet.ServerIp}:{this._appSet.ServerPort}{(this._appSet.ServerUpdateDataPath.IndexOf("/") < 0 ? "/" : "")}{this._appSet.ServerUpdateDataPath}";

                //var url = "http://114.55.145.41:8888/static/102.apk";
                var path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
                var fileName = "temp.apk";
                var fullPath = $"{path}/{fileName}";
                await Task.Factory.StartNew(() =>
                {
                    downloadIsSuccess = HttpHelper.DownloadFile(url, fullPath);
                });
                
                if (downloadIsSuccess)
                {
                    InstallApk(fullPath);
                }
            }
        }

        private void InstallApk(string filePath)
        {
            try
            {
                Intent intent = new Intent(Intent.ActionView);
                intent.SetFlags(Intent.Flags);
                var file= new Java.IO.File(filePath);
                Uri uri = null;

                if(Build.VERSION.SdkInt>=BuildVersionCodes.M)
                {
                    intent.AddFlags(ActivityFlags.GrantReadUriPermission);
                    uri = FileProvider.GetUriForFile(Application.Context, Application.Context.PackageName + ".fileprovider", file);
                }
                else
                {
                    uri = Uri.FromFile(file);
                    intent.SetAction(Intent.ActionView);
                }
                //var uri = FileProvider.GetUriForFile(Application.Context, Application.Context.PackageName+ ".android7.fileprovider", file);
                //intent.AddFlags(ActivityFlags.GrantReadUriPermission);

                intent.SetDataAndType(uri, "application/vnd.android.package-archive");
                StartActivity(intent);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        #endregion

        private void InitControlEvents()
        {

        }

        /// <summary>
        /// 数据库初始化
        /// </summary>
        public void SetDb()
            => DbContext.DbC.InitDb();

        /// <summary>
        /// 过期数据提示
        /// </summary>
        private void SearchOverDateMedicine()
        {
            try
            {
                var startDate = DateTime.Now.AddDays(Convert.ToInt32(this._appSet.MedicineOverDay)*-1);
                var allData = DbContext.DbC.ListQuery<Models.Medicine>(s =>s.ExpirationDate>startDate);
                //var overData = new List<Models.Medicine>();
                //foreach (var item in allData)
                //{
                //    var overDate = Convert.ToDateTime(item.ExpirationDate);
                //    if (overDate > startDate)
                //        continue;

                //    overData.Add(item);
                //}

                //if (overData.Count > 0)
                //    Helpers.MessageShow.ShowNoticeMsg(this,
                //                                    "过期数据提示", 
                //                                    $"您有{overData.Count}个药品即将过期请注意查看！！！");    
                if (allData.Count > 0)
                    Helpers.MessageShow.ShowNoticeMsg(this,
                                                    "过期数据提示", 
                                                    $"您有{allData.Count}个药品即将过期请注意查看！！！");
            }
            catch (Exception ex)
            {
                Helpers.MessageShow.ShowShortMsg(this, $"超时数据查询异常，{ex.Message}");
            }
        }

        public override void OnBackPressed()
        {
            DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
            if (drawer.IsDrawerOpen(GravityCompat.Start))
                drawer.CloseDrawer(GravityCompat.Start);
            else
                base.OnBackPressed();
        }

        /// <summary>
        /// 建立菜单
        /// </summary>
        /// <param name="menu"></param>
        /// <returns></returns>
        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            //将菜单注入到Toolbar中
            MenuInflater.Inflate(Resource.Menu.menu_main, menu);
            return true;
        }

        /// <summary>
        /// 菜单按钮选中事件
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            int id = item.ItemId;
            if (id == Resource.Id.action_settings)
            {
                StartActivity(new Intent(this, typeof(AppSetActivity)));
            }

            return base.OnOptionsItemSelected(item);
        }

        private void FabOnClick(object sender, EventArgs eventArgs)
        {
            View view = (View)sender;

            Snackbar.Make(view, "联系邮箱：705051461@qq.com", Snackbar.LengthShort)
                .SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
        }

        /// <summary>
        /// 左划导航按钮选中事件
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool OnNavigationItemSelected(IMenuItem item)
        {
            int id = item.ItemId;

            if (id == Resource.Id.nav_gallery)
                StartActivity(new Intent(this, typeof(InsertActivity)));
            else if (id == Resource.Id.nav_share)
                //查看药品信息
                StartActivity(new Intent(this, typeof(AllInfoActivity)));
            else if (id == Resource.Id.nav_send)
                //查询药品信息
                StartActivity(new Intent(this, typeof(QueryInfoActivity)));
            else if (id == Resource.Id.nav_export)
                //导出数据
                ExportHandle();
            else if (id == Resource.Id.nav_import)
                //导入数据
                ImportHandle();
            else if (id== Resource.Id.nav_overdate)
                //过期药品信息
                StartActivity(new Intent(this, typeof(ExpiredInfoActivity)));

            DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
            drawer.CloseDrawer(GravityCompat.Start);
            return true;
        }

        /// <summary>
        /// 所需要的读写权限
        /// </summary>
        private String[] PERMISSIONS_STORAGE =
            {
                "android.permission.READ_EXTERNAL_STORAGE",
                "android.permission.WRITE_EXTERNAL_STORAGE"
            };

        /// <summary>
        /// 检查权限
        /// </summary>
        private void CheckPermission()
        {
            //检查权限
            var permission = ActivityCompat.CheckSelfPermission(this, "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != Android.Content.PM.Permission.Granted)
                ActivityCompat.RequestPermissions(this, PERMISSIONS_STORAGE, 1);
        }

        /// <summary>
        /// 导出数据处理
        /// </summary>
        private void ExportHandle()
        {
            CheckPermission();
            var result = Android.OS.Environment.ExternalStorageState.Equals(Android.OS.Environment.MediaMounted);

            if (result)
            {
                var path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
                Helpers.MessageShow.ShowShortMsg(this, path);
                var fileName = "medicine.fi";
                var allData = DbContext.DbC.AllDataQuery<Medicine.Models.Medicine>();
                var jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(allData);
                using (var file = new FileStream($"{path}/{fileName}", FileMode.Create, FileAccess.Write))
                {
                    var fileArray = System.Text.Encoding.UTF8.GetBytes(jsonStr);
                    file.Write(fileArray, 0, fileArray.Length);
                    file.Flush();
                    file.Close();
                }
                Helpers.MessageShow.ShowShortMsg(this, $"导出完成，路径为：{path}/{fileName}");
            }
        }

        /// <summary>
        /// 导入文件选择
        /// </summary>
        private void ImportHandle()
        {
            CheckPermission();

            Intent intent = new Intent(Intent.ActionOpenDocument);
            intent.AddCategory(Intent.CategoryOpenable);
            intent.SetType("*/*");
            StartActivityForResult(Intent.CreateChooser(intent, "选择数据备份文件"), 20);
        }

        /// <summary>
        /// 导入文件选中后处理
        /// </summary>
        /// <param name="requestCode"></param>
        /// <param name="resultCode"></param>
        /// <param name="data"></param>
        protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        {
            if (data == null)
            {
                Helpers.MessageShow.ShowShortMsg(this, "请选择数据文件");
                return;
            }

            ReadFileHandle(data.Data);
        }

        /// <summary>
        /// 读取文件，并将数据插入数据库
        /// </summary>
        /// <param name="uri"></param>
        private void ReadFileHandle(Android.Net.Uri uri)
        {
            var realyUri = Helpers.OtherHelpers.RealyPath.GetRealyPath(this, uri);
            if (File.Exists(realyUri))
            {
                try
                {
                    using (var file = new FileStream(realyUri, FileMode.Open, FileAccess.Read))
                    {
                        var buffArray = new byte[file.Length];
                        file.Read(buffArray, 0, buffArray.Length);
                        var dataJson = System.Text.Encoding.UTF8.GetString(buffArray);
                        if (string.IsNullOrEmpty(dataJson))
                        {
                            Helpers.MessageShow.ShowShortMsg(this, "文件内容读取为空");
                            return;
                        }

                        var dataArray = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Models.Medicine>>(dataJson);
                        if (dataArray != null && dataArray.Count > 0)
                        {
                            var insertCount = DbContext.DbC.InsertArray<Models.Medicine>(dataArray, true);
                            Helpers.MessageShow.ShowShortMsg(this, $"成功导入数据：{insertCount}条");
                        }
                        else
                            Helpers.MessageShow.ShowShortMsg(this, "文件内容读取数据为空");
                    }
                }
                catch (Exception ex)
                {
                    Helpers.MessageShow.ShowLongMsg(this, ex.Message);
                }
            }
            else
                Helpers.MessageShow.ShowShortMsg(this, "系统未能读取文件");
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

